<template>
  <div class="week-all-day-event">
      <div class="week-all-day-event-list" :style="{height:`calc(${maxEvent > 3 ? 3 : maxEvent} * 20px)`}">
            <template v-for="(item, index) in weekEvent">
                <div 
                    :key="item.id" 
                    :class="['all-day-event-cell', item.isEdit ? '' : 'all-day-event-disabled', item.complete ? 'event-complete' : '']" 
                    :data-index="index" 
                    :style="getStyle(item)" 
                    v-if="checkRank(item) < 3" 
                    :data-id="item.id" 
                    @mousedown="getEvent($event, index)" 
                    @mouseup="itemUp"
                    @mouseover="itemOver($event)"
                >
                    <el-popover
                        :placement="placement"
                        :width="270"
                        trigger="hover"
                        popper-class="event-detail-pop"
                        :persistent="false"
                    >
                        <template #reference>
                            <span class="slot-data" :style="{textDecoration: item.state == 2 ? 'line-through' : 'unset'}"> 
                                <el-tag size="small" style="margin-right:5px" @click.stop.prevent="jumpModel($event, index)" v-if="item.relateItems && item.relateItems.length > 0">
                                    {{ (item.relateItems && item.relateItems.length > 0) ? item.relateItems[0].label : '' }}
                                </el-tag>
                                <slot :targetType="item.targetType" :codeName="item.codeName" :state="item.state" :title="item.title" :actionStartTime="item.actionStartTime" :actionEndTime="item.actionEndTime"></slot>
                            </span>
                        </template>
                        <div class="event-detail">
                            <el-row align="middle" justify="start" style="border-bottom: 1px solid #f0f0f0;padding-bottom: 5px;">
                                <el-button
                                    size="small"
                                    type="primary"
                                    link
                                    :icon="View"
                                    @click="readInfo(item)"
                                    >查看</el-button
                                >
                                <el-button 
                                    v-if="item.state == 0 && item.sponsor.userId == userId"
                                    size="small" 
                                    type="primary" 
                                    link 
                                    @click="editInfo(item)"
                                >
                                    <edit-two theme="outline" size="14" style="margin-right:5px;margin-top:2px" />
                                    编辑
                                </el-button>
                                <el-button 
                                    v-if="item.state == 0 || item.state == 1"
                                    size="small" 
                                    type="primary" 
                                    link 
                                    @click="completeEvent(item, index)" style="margin-left:0;"
                                >
                                    <done-all theme="outline" size="16" style="margin-right:5px"/>
                                    完成
                                </el-button>
                                <el-button 
                                    v-if="
                                        item.state == -2 || 
                                        (item.state == 0 && item.sponsor.id == userId) || 
                                        (item.state == 1 && item.sponsor.id == userId) ||
                                        item.state == 2 || item.state == 3 || item.state == 4 || item.state == 5
                                    "
                                    size="small" 
                                    type="danger" 
                                    link 
                                    style="margin-left:0" 
                                    @click="delEvent(item)"
                                >
                                    <delete theme="outline" size="14" style="margin-right:5px;" />
                                    删除
                                </el-button>
                                <el-button 
                                    v-if="item.state == -1 && item.approverIds.includes(userId)"
                                    size="small"
                                    type="primary"
                                    link
                                    style="margin-left: 0; margin-top: 2px"
                                    @click="approverAccess(item)"
                                >
                                    <el-icon><Check /></el-icon>
                                    通过
                                </el-button>
                                <el-button 
                                    v-if="item.state == -1 && item.approverIds.includes(userId)"
                                    size="small"
                                    type="danger"
                                    link
                                    style="margin-left: 0; margin-top: 2px"
                                    @click="approverReject(item)"
                                >
                                    <close theme="outline" size="14" style="margin-right: 5px; margin-top: 1px" />
                                    拒绝
                                </el-button>
                            </el-row>
                            <el-row justify="start" style="margin: 10px 0;flex-wrap: nowrap;">
                                <round 
                                    style="margin: 0 6px 0 2px"
                                    theme="filled" 
                                    size="8" 
                                    fill="#18a058" 
                                />
                                <div class="event-detail-data">{{ item.title }}</div>
                            </el-row>
                            <el-row style="flex-wrap: nowrap;">
                                <calendar-dot theme="outline" size="14" />
                                <div class="event-detail-data">{{ formatDurationTime(item) }}</div>
                            </el-row>
                            <el-row style="margin-top:5px;flex-wrap: nowrap;">
                                <user theme="outline" size="14" />
                                <div class="event-detail-data">{{ (item.relateItems && item.relateItems.length > 0) ? item.relateItems[0].label : '-' }}</div>
                            </el-row>
                            <el-row justify="start" style="margin-top: 5px;flex-wrap: nowrap;">
                                <el-icon style="margin-right: 8px;margin-top: 4px;" color="#18a058"><CollectionTag /></el-icon>
                                <el-tag size="small" class="showAllTag">{{ item.codeName }}</el-tag>
                            </el-row>
                        </div>
                    </el-popover>
                </div>
            </template>
      </div>
      <div class="more-event-options" v-if="getAccount > 3">
            <div v-for="item in weekAccount" :key="item.id" class="more-event" :style="{visibility: item[1] > 3 ? 'visible' : 'hidden'}" @click="openMore(item[0])">+{{item[1] - 3}} 更多事件</div>
      </div>
      <div class="more-event-model" v-if="showMore">
          <div class="more-bg" @click="showMore = false"></div>
          <div class="more-content" :style="{left: `calc(${moreData.left} * (100% - ${moreData.left == (week.length - 1) ? 12 : 10}px))`}" ref="moredom">
                <div class="more-title-options">
                    <div class="more-time">{{moreData.info.fullDate}}</div>
                    <div class="more-close-btn" @click="showMore = false">
                        <close theme="outline" size="14" fill="#333"/>
                    </div>
                </div>
                <div class="more-evnet-list">
                    <div class="more-event-item" v-for="item in moreData.list" :key="item.id" :style="{background:item.background, color: item.color}" :data-id="item.id" @click.prevent.stop="getModelEvent">
                        <el-tag size="small" style="margin-right:5px" @click.stop.prevent="jumpModel($event, index)" v-if="item.relateItems && item.relateItems.length > 0">
                            {{ (item.relateItems && item.relateItems.length > 0) ? item.relateItems[0].label : '' }}
                        </el-tag>
                        <slot :targetType="item.targetType" :codeName="item.codeName" :state="item.state" :title="item.title" :actionStartTime="item.actionStartTime" :actionEndTime="item.actionEndTime"></slot>
                    </div>
                </div>
          </div>
      </div>
  </div>
</template>

<script>
import { Close, CalendarDot, User, EditTwo, DoneAll, Delete, Round } from '@icon-park/vue-next';
import { CollectionTag, Check, View } from '@element-plus/icons-vue'
import { toRefs, computed, watch, nextTick, onMounted, ref } from 'vue'
import { checkCurrentWeekEvents, getAnyTimeEvent, formatTime } from '../lib/event'
import { format, formatShortTime } from '../lib/utils'
import Cookies from 'js-cookie'
export default {
    name: 'AllDayWeekEventItem',
    props: {
        event: {
            type: Array,
            default() {
                return []
            }
        },
        week: {
            type: Array,
            default() {
                return []
            }
        },
        dropData: {
            type: Object,
            default() {
                return {}
            }
        }
    },
    components: {
        Close,
        CalendarDot,
        User,
        EditTwo,
        DoneAll, 
        Delete,
        Round,
        CollectionTag, 
        Check
    },
    emits: ['exchangeDate', 'editInfo', 'delEvent', 'completeEvent'],
    setup(props, context) {
        const { event, week, dropData } = toRefs(props)
        const len = week.value.length
        // eslint-disable-next-line no-unused-vars
        const dropMessage = ref(dropData.value)
        let startWeek = new Date(week.value[0].fullDate + ' 00:00:00').getTime()
        let endWeek = new Date(week.value[len - 1].fullDate + ' 23:59:59').getTime()
        let weekEvent = ref([])
        let weekAccount = ref([])
        let showMore = ref(false)
        let moreData = ref({})
        let maxEvent = ref(0)
        let moredom = ref(null)
        let canUp = true
        let events = event
        const selectedInfo = ref(null)
        const userId = Cookies.get('userId')
        const eventModel = ref({
            top: `unset`,
            left: `unset`,
            right: `unset`,
            bottom: `unset`,
            background: ``,
            width: ``
        })
        const clickStart = ref(null)
        const placement = ref('bottom-start') // pop框的位置
        let dropIndex = -1
        let dropInfo = null
        const getStyle = computed(() => {
            return (e) => {
                let diff = Math.ceil((e.end - e.start) / 1000 / 86400)
                let width = 0
                let left = 0
                if(diff == 1) {
                    // 判断是否同一天
                    if(new Date(e.start).getDay() != new Date(e.end).getDay()){
                        diff += 1
                    }
                }
                if(startWeek <= e.start && endWeek >= e.end && diff <= 7) {
                    const day = new Date(e.start).getDay() == 0 ? len : new Date(e.start).getDay()
                    width = len * diff < 0 ? 0 : `calc(100% / ${len} * ${diff} - 4px)`
                    left = `calc(100% / ${len} * ${day - 1} + 2px)`
                } else {
                    // 开头在当前周， 日期大于当前周的第一天的时间,且小于结尾的时间 那么它就在当前周
                    if(startWeek <= e.start && e.start <= endWeek) {
                        // 获取当前周内有几天
                        const currentDay = new Date(e.start).getDay() == 0 ? len : new Date(e.start).getDay()
                        const diffDay = Math.ceil(len - currentDay + 1)
                        width = len * diff < 0 ? 0 : `calc(100% / ${len} * ${diffDay} - 4px)`
                        left = `calc((100% / ${len}) * ${len - diffDay} + 2px)`
                    }else if(startWeek >= e.start) {
                        // 开头不在当前周, 日期小于当前周的第一天, 必然在上一周
                        left = 0
                        const currentDay = new Date(e.end).getDay() == 0 ? len : new Date(e.end).getDay()
                        if(endWeek <= e.end) {
                            // 结尾在下周, 结尾大于当前周的结尾时间, 肯定在下周
                            width = `calc(100% / ${len} * ${len} - 4px)`
                        }else{
                            width = `calc(100% / ${len} * ${currentDay} - 4px)`
                        }
                    }
                }
                if(left == 0){
                    left = '2px'
                }
                const position = {
                    width,
                    left,
                    top: getTop(e),
                    background: e.background,
                    color: e.color
                }
                return {
                    ...position
                }
            }
        })
         // 格式化时间
         const formatDurationTime = computed(() => {
            return item => {
                if(!item.actionStartTime) return ''
                return formatShortTime(item)
            }
        })
        // 获取距离顶部的距离
        const getTop = (e) => {
            let top = 0
            const dayEvent = weekEvent.value
            let currentDayEvent = getAnyTimeEvent(e.startDate, dayEvent)
            currentDayEvent.sort((a, b) => b.release - a.release)
            const eventIdx = currentDayEvent.findIndex(item => {
                return item.id == e.id
            })
            top = `calc(20px * ${eventIdx})`
            return top
        }
        // 获取当前周的事件
        const getCurrentWeek = () => {
            maxEvent.value = 0
            startWeek = new Date(week.value[0].fullDate + ' 00:00:00').getTime()
            endWeek = new Date(week.value[len - 1].fullDate + ' 23:59:59').getTime()
            weekEvent.value = checkCurrentWeekEvents(event.value, week.value)
            weekEvent.value.sort((a, b) => b.release - a.release)
            let deArr = new Array() // 合计每一天的事件数量
            for(let i = 0; i < week.value.length; i ++) {
                deArr.push([i, getAnyTimeEvent(week.value[i].fullDate, weekEvent.value).length])
            }
            weekAccount.value = deArr
            let num = 0
            while(num < deArr.length) {
                maxEvent.value = Math.max(maxEvent.value, deArr[num][1])
                num ++
            }
        }
        // 打开更多事件拟态框
        const openMore = (e) => {
            showMore.value = true
            moreData.value['left'] = e
            moreData.value['info'] = week.value[e]
            moreData.value['list'] = getAnyTimeEvent(week.value[e].fullDate, weekEvent.value)
        }
        const getAccount = computed(() => {
            let account = []
            weekAccount.value.forEach(e => {
                account.push(e[1])
            })
            account.sort()
            return account[len - 1]
        })
        // 获取当前事件在当天排行
        const checkRank = computed(() => {
            return (e) => {
                const dayEvent = weekEvent.value
                let currentDayEvent = getAnyTimeEvent(e.startDate, dayEvent)
                currentDayEvent.sort((a, b) => b.release - a.release)
                const eventIdx = currentDayEvent.findIndex(item => {
                    return item.id == e.id
                })
                return eventIdx
            }
        })
        // 点击事件
        const getEvent = (e, index) => {
            selectedInfo.value = null
            clickStart.value = new Date().getTime()
            dropIndex = index
            dropInfo = e
            canUp = true
            weekEvent.value[index]['active'] = true
            setTimeout(() => {
                if(canUp) {
                    dragStart(e, index)
                }else{
                    if(weekEvent.value[dropIndex]){
                        weekEvent.value[dropIndex]['active'] = false
                    }
                }
            }, 350)
        }
        const dragStart = (event, index) => {
            if(!weekEvent.value[index].isEdit){
                context.emit('getEvent', dropInfo)
                canUp = false
                return false
            }
            const startX = event.clientX - 5
            let disX = startX - event.target.offsetLeft;
            const windowWidth = document.querySelector('.week-day-container').clientWidth - 2
            const cubeWidth = document.querySelectorAll('.week-cell')[0].clientWidth
            document.onmousemove = ev => {
                if(canUp && dropIndex > - 1) {
                    let e = ev || window.event;
                    let l = e.clientX - disX;
                    l = range(l, 0, windowWidth - event.target.offsetWidth)
                    event.target.style.left =`${l}px`;
                }
            }
            // eslint-disable-next-line no-unused-vars
            document.onmouseup = ev => {
                document.onmousemove = null;
                if(canUp && dropIndex > - 1) {
                    weekEvent.value[dropIndex]['active'] = false
                    let e = ev || window.event;
                    let d = Math.floor((e.clientX - disX) / cubeWidth) ;// 移动的距离
                    d = d < 0 ? 0 : d
                    d = d > 7 ? 6 : d
                    const item = weekEvent.value[dropIndex]
                    const index = events.value.findIndex(e => {
                        return e.id == item.id
                    })
                    const date = week.value[d].fullDate
                    let newTime = new Date(date + ' ' + item.hours.split('-')[0]).getTime()
                    if(isNaN(newTime)){
                        return false
                    }
                    events.value[index].actionStartTime = format(new Date(newTime), 'yyyy-MM-dd HH:mm')
                    events.value[index].actionEndTime = format(new Date(new Date(events.value[index].actionStartTime).getTime() + item.release), 'yyyy-MM-dd HH:mm')
                    events.value[index].start = new Date(events.value[index].actionStartTime).getTime()
                    events.value[index].end = new Date(events.value[index].actionEndTime).getTime()
                    events.value[index] = formatTime(events.value[index])
                    getCurrentWeek()
                    context.emit('exchangeDate', events.value[index])
                    canUp = false
                }
            }
        }
        const range = (loc, min, max) => {
            if(loc > max) {
                return max;
            }else if(loc < min) {
                return min;
            }else {
                return loc;
            }
        }
        const itemUp = () => {
            const end = new Date().getTime()
            if(end - clickStart.value < 350){
                canUp = false
                context.emit('getEvent', dropInfo)
                return false
            }
            if(weekEvent.value[dropIndex]){
                weekEvent.value[dropIndex]['active'] = false
            }
        }
        // 鼠标滑动
        const itemOver = e => {
            const width = e.target.clientWidth
            const leftX = e.pageX - width
            if(leftX < 280) {
                placement.value = 'bottom'
            }else{
                placement.value = 'bottom'
            }
        }
        // 点击model事件
        const getModelEvent = e => {
            nextTick(() => {
                const left = moredom.value.offsetLeft
                context.emit('getModelEvent', { e, left })
            })
        }
        // 编辑信息
        const editInfo = (e) => {
            // let obj = {}
            // for(let key in e) {
            // obj[key] = e[key]
            // }
            context.emit('editInfo', e)
        }
         // 删除
        const delEvent = e => {
            context.emit('delEvent', e)
        }
        // 完成事件
        const completeEvent = (e, index) => {
            // weekEvent.value[index].complete = true
            context.emit('completeEvent', e)
        }
        // 模块跳转
        const jumpModel = (e, index) => {
            console.log(e, index)
        }
        // 审批通过
        const approverAccess = e => {
            context.emit('approverAccess', e)
        }
        // 审批拒绝
        const approverReject = e => {
            context.emit('approverReject', e)
        }
        // 查看
        const readInfo = (e) => {
            context.emit("readInfo", e);
        }
        watch(() => week.value, 
            () => {
                nextTick(() => {
                    getCurrentWeek()
                })
            },
            {
                deep: true
            }
        )
        watch(() => event.value, 
            () => {
                nextTick(() => {
                    getCurrentWeek()
                })
            },
            {
                deep: true
            }
        )
        watch(() => dropData.value,
            (oldVal, newVal) => {
                dropMessage.value = oldVal || newVal
            },
            {
                deep: true
            }
        )
        onMounted(() => {
            nextTick(() => {
                getCurrentWeek()
            })
        })
        return {
            getStyle,
            weekEvent,
            weekAccount,
            showMore,
            openMore,
            moreData,
            getAccount,
            checkRank,
            maxEvent,
            getEvent,
            getModelEvent,
            moredom,
            selectedInfo,
            eventModel,
            itemUp,
            editInfo,
            delEvent,
            completeEvent,
            itemOver,
            placement,
            formatDurationTime,
            jumpModel,
            userId,
            approverAccess,
            approverReject,
            View,
            readInfo
        }
    }
}
</script>

<style scoped lang="scss">
.week-all-day-event{
    padding-bottom: 5px;
    padding-right: 2px;
    position: relative;
    margin-top: 60px;
}
.week-all-day-event .all-day-event-cell{
    position: absolute;
    border-radius: 2px;
    background: #eaf4fc;
    color: var(--ss-color-primary);
    padding: 0 5px;
    font-size: 12px;
    height: 20px;
    line-height: 20px;
    overflow: hidden;
    border: 1px solid #fff;
    box-sizing: border-box;
    cursor: pointer;
    &::after{
        content: "";
        position: absolute;
        right: 3px;
        bottom: 3px;
        width: 4px;
        height: 4px;
        border-right: 1px solid var(--ss-color-primary);
        border-bottom: 1px solid var(--ss-color-primary);
        opacity: .7;
    }
}
.week-all-day-event .all-day-event-disabled{
    display: none;
}
.week-all-day-event .more-event-options{
    position: relative;
    display: flex;
    align-items: stretch;
}
.week-all-day-event .more-event-options .more-event{
    position: relative;
    flex: 1;
    overflow: hidden;
    text-align: center;
    margin-top: 2px;
    cursor: pointer;
    font-size: 12px;
    color: #909399;
}
.more-event-model{
    position: relative;
    z-index: 10;
    width: calc(100% / 7 + 10px);
    top: -140px;
}
.more-event-model .more-bg{
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 998;
}
.more-event-model .more-content{
    position: absolute;
    background: #fff;
    height: 180px;
    top: 0;
    left: 0;
    width: 100%;
    box-shadow: 0 0 10px 0 rgba(0,0,0,.1);
    border: 1px solid #E4E7ED;
    z-index: 999;
    transition: .2s;
}
.more-event-model .more-content .more-title-options{
    display: flex;
    align-items: center;
    justify-content: space-between;
    background: #F2F6FC;
    padding: 5px;
    font-size: 14px;
    color: #303133;
}
.more-event-model .more-content .more-evnet-list{
    padding: 5px;
    max-height: calc(100% - 30px);
    overflow: auto;
}
.more-event-model .more-content .more-evnet-list .more-event-item{
    border-radius: 2px;
    background: #eaf4fc;
    color: var(--ss-color-primary);
    padding: 0 5px;
    font-size: 12px;
    height: 20px;
    line-height: 20px;
    margin:2px 2px 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.more-event-model .more-close-btn{
    cursor: pointer;
}
.move-event{
    border-radius: 2px;
    background: #eaf4fc;
    color: var(--ss-color-primary);
    padding: 0 5px;
    font-size: 12px;
    height: 20px;
    line-height: 20px;
    border: 1px solid #fff;
    box-sizing: border-box;
    overflow: hidden;
    position: fixed;
}
.event-complete{
    text-decoration: line-through;
}
.slot-data{
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    display: block;
}
:deep(.el-tag--small){
    height: 16px;
    .el-tag__content{
        max-width: 76px;
        overflow:hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }
}
:deep(.showAllTag){
    .el-tag__content {
        max-width: unset;
    }
}
:deep(.el-button--small [class*=el-icon]+span){
  margin-left: 0;
}
</style>